<?php

class Backoffice_GroupController extends CC_Controller
{
    /**
     * Display all groups with pagination
     * 
     * URL: /backoffice/group/index
     */
    public function indexAction()
    {
        // DQL query to be paginated and passed to view
        $dql = $this->_em->createQuery('SELECT g FROM CC\Entity\Group g ORDER BY g.name ASC');
        
        $groups = new Zend_Paginator(new DoctrineExtensions\Paginate\PaginationAdapter($dql));
        $groups->setCurrentPageNumber($this->_getPage())->setItemCountPerPage(20)->setPageRange(10);
        
        $this->view->groups = $groups;
    }

    /**
     * Create a new group
     * 
     * URL: /backoffice/group/create
     */
    public function createAction()
    {
        // Create form object
        $form = new Backoffice_Model_FormGroup($this->_em);
        $request = $this->getRequest();
        
        // Check if this is a POST request
        if($request->isPost())
        {
            // Check if form is valid
            if($form->isValid($request->getParams()))
            {
                // Create group
                $group = new CC\Entity\Group();
                $group->setName($request->getParam('name'));
                
                // Set parent only if set in form
                if($request->getParam('parentGroup') != '')
                    $group->setParent($this->_em->getReference('CC\Entity\Group', $request->getParam('parentGroup')));
                
                $this->_em->persist($group);
                $this->_em->flush();
                
                // Success message with redirect to index action
                $this->_helper->messenger('success', sprintf(Zend_Registry::get('config')->messages->group->create, $request->getParam('name')));
                return $this->_helper->redirector('index', 'group', 'backoffice');
            }
            else
            {
                // Set view errors
                $this->view->errors = $form->getErrors();
            }
        }
        
        // Display form
        $this->view->form = $form;
    }
    
    /**
     * Update the group passed by the 'id' GET parameter
     * 
     * URL: /backoffice/group/update/id/?
     */
    public function updateAction()
    {
        $isInvalid = false;
        $request = $this->getRequest();
        
        // Ensure that an id was passed
        if($request->getParam('id'))
        {
            // Get group from id
            $group = $this->_em->getRepository('CC\Entity\Group')->findOneById($request->getParam('id'));
            
            // Check if group is valid
            if($group !== null)
            {
                // Create form instance and modify submit button
                $form = new Backoffice_Model_FormGroup($this->_em);
                $form->getElement('submit')
                     ->setLabel('Update group');
                
                // Check if request is post
                if($request->isPost())
                {
                    // Check if form is valid
                    if($form->isValid($request->getParams()))
                    {
                        // Update form values
                        $group->setName($request->getParam('name'));
                        
                        // Update parent group only if one is selected
                        if($request->getParam('parentGroup'))
                            $group->setParent($this->_em->getReference('CC\Entity\Group', $request->getParam('parentGroup')));
                        
                        // Update
                        $this->_em->persist($group);
                        $this->_em->flush();
                        
                        // Display success message on redirect to index action
                        $this->_helper->messenger('success', sprintf(Zend_Registry::get('config')->messages->group->update, $request->getParam('name')));
                        return $this->_helper->redirector('index', 'group', 'backoffice');
                    }
                    else
                    {
                        // Pass errors to form
                        $this->view->errors = $form->getErrors();
                    }
                }
                
                // Build form data to populate form with and display it
                $formData['name'] = $group->getName();
                if($group->getParent() !== null)
                    $formData['parentGroup'] = $group->getParent()->getId();
                
                $form->populate($formData);
                $this->view->form = $form;
            }
            else
            {
                $isInvalid = true;
            }
        }
        else 
        {
            $isInvalid = true;
        }
        
        // Invalid group, redirect to index action
        if($isInvalid)
        {
            $this->_helper->messenger('error', Zend_Registry::get('config')->messages->group->invalid);
            return $this->_helper->redirector('index', 'group', 'backoffice');
        }
    }
    
    /**
     * Delete the group passed by the 'id' GET parameter
     * 
     * URL: /backoffice/group/delete/id/?
     */
    public function deleteAction()
    {
        $request = $this->getRequest();
        
        // If no id, display error message on index action redirect
        if(!isset($request->id))
        {
            $this->_helper->messenger('error', Zend_Registry::get('config')->messages->group->invalid);
            return $this->_helper->redirector('index', 'group', 'backoffice');
        }
            
        $group = $this->_em->getRepository('CC\Entity\Group')->findOneById($request->id);
        
        // Check if group is valid
        if($group !== null)
        {
            // @TODO: Remove group and dependent flippers
            // If the group has flippers assigned, then it wont be able to be removed
            // Display error on index action redirect
            if(count($group->getFlippers()))
            {
                $this->_helper->messenger('error', 'Unable to remove group. Please remove dependencies first (Manual)');
                return $this->_helper->redirector('index', 'group', 'backoffice');
            }
            
            $groupName = $group->getName();
            
            // Remove entity
            $this->_em->remove($group);
            $this->_em->flush();
            
            // Display message on redirect
            $this->_helper->messenger('success', sprintf(Zend_Registry::get('config')->messages->group->delete, $groupName));
            $this->_helper->redirector('index', 'group', 'backoffice');
        }
        else
        {
            // Error message and redirect
            $this->_helper->messenger('success', Zend_Registry::get('config')->messages->group->invalid);
            return $this->_helper->redirector('index', 'group', 'backoffice');
        }
    }

    /**
     * Edit the flippers for the group passed by GET param 'id'
     * This method will create flippers if they do not exist.
     * Any checkboxes that are not ticked will be handled as 'deny',
     * ticked checkboxes are handled as 'allow' in the ACL
     * 
     * URL: /backoffice/group/flippers/id/?
     */
    public function flippersAction()
    {
        $request = $this->getRequest();
        
        // Check if id parameter set
        if($request->getParam('id'))
        {
            // Get group from id
            $group = $this->_em->getRepository('CC\Entity\Group')->findOneById($request->getParam('id'));
            
            // Check if group is valid
            if($group !== null)
            {
                $form = new Backoffice_Model_FormGroupFlipper($this->_em);
                
                if($request->isPost())
                {
                    if($form->isValid($request->getParams()))
                    {
                        $formValues = $form->getValues();
                        Zend_Debug::dump($formValues);
                        // Iterate through the flags
                        foreach($formValues['flipper'] as $flagId => $privilegeAccess)
                        {
                            $flag = $this->_em->getRepository('CC\Entity\Flag')->findOneById($flagId);
                            
                            foreach($privilegeAccess as $privilegeId => $allow)
                            {
                                // Check if flipper exists
                                $flipper = $this->_em->getRepository('CC\Entity\Flipper')->findOneBy(array("privilege" => $privilegeId, "flag" => $flagId, "group" => $group->getId()));
                                
                                // Create new flipper if one doesnt exist
                                if($flipper === null)
                                {
                                    $flipper = new CC\Entity\Flipper();
                                    $flipper->setPrivilege($this->_em->getReference('CC\Entity\Privilege', $privilegeId));
                                    $flipper->setGroup($this->_em->getReference('CC\Entity\Group', $group->getId()));
                                    $flipper->setFlag($this->_em->getReference('CC\Entity\Flag', $flagId));
                                }
                                
                                // Set allow/deny on privilege
                                $flipper->setAllow(($allow == '1' ? true : false));
                                
                                // Save flipper
                                $this->_em->persist($flipper);
                                $this->_em->flush();
                                
                                unset($flipper);
                            }
                        }
                        
                        // Regenerate the ACL and save in registry and APC
                        CC_FlagFlippers_Manager::save();
                        
                        // Display success message and redirect to group index action
                        $this->_helper->messenger('success', sprintf(Zend_Registry::get('config')->messages->group->flipper->update, $group->getName()));
                        return $this->_helper->redirector('index', 'group', 'backoffice');
                    }
                }
                
                // Get the flippers for the current group
                $flippers = $this->_em->getRepository('CC\Entity\Flipper')->getFlippersForGroup($group->getId());
                
                // Populate form and send to view
                $form->populate($flippers, $group->getId());
                $this->view->groupName = $group->getName();
                $this->view->form = $form;
            }
            else
            {
                // Invalid group id. Message and redirect
                $this->_helper->messenger('error', 'Invalid group');
                return $this->_helper->redirector('index', 'group', 'backoffice');
            }
        }
        else
        {
            // No group id. Message and redirect
            $this->_helper->messenger('error', 'Invalid group');
            return $this->_helper->redirector('index', 'group', 'backoffice');
        }
    }
}

?>